package com.darren.euc.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import Com.FirstSolver.Splash.FaceId;
import Com.FirstSolver.Splash.FaceIdAnswer;
import Com.FirstSolver.Splash.FaceId_ErrorCode;
import Com.FirstSolver.Splash.FaceId_Item;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

public class HanWangUtil {

	private static String DEVICECHARSET = "GBK";
	
	/**
	 * 会员绑卡
	 * @param mainDevice 主设备信息，主要包括 ip，port，password,deviceName 连接状态 connectionStatus
	 * @param otherDevice 其它设备信息， 主要包括 ip，port，password,deviceName,连接状态 connectionStatus
	 * @param cardId	手环ID(手环编号)
	 * @param memberInfo 会员信息
	 * @return
	 */
	public static String bindHandCard(Map<String,Object> mainDevice,List<Map<String,Object>> otherDevices,Integer cardId,Map<String,Object> memberInfo){
		String message = "";
		String result = "";
		FaceId_Item[] ItemCollection = null;
		String mainIp = (String)mainDevice.get("ip");
		Integer mainPort = (Integer)mainDevice.get("port");
		String mainPassword = (String)mainDevice.get("password");		
		String mainName = (String)mainDevice.get("deviceName");
		Integer connectStatus = (Integer)mainDevice.get("connectStatus");
		if(connectStatus == 2){
			message = String.format("连接主设备【%s】失败！", mainName);
			return message;
		}
		String employeeInfoString = getEmployeeInfo(mainIp,mainPort,mainPassword,cardId);
		if("fail".equals(employeeInfoString)){
			message = String.format("连接主设备【%s】失败！", mainName);
			return message;
		}else{
			ItemCollection = FaceId_Item.GetAllItems(employeeInfoString);
			if (ItemCollection != null){
				for (FaceId_Item item : ItemCollection){
					if("result".equals(item.name) && "failed".equals(item.value)){
						message = String.format("主设备【%s】中未查找到 id 为 %s 的人员信息",mainName,cardId);
						return message;
					}
				}
				StringBuilder sb = new StringBuilder();
				sb.append("SetEmployee( ");
				for (FaceId_Item item : ItemCollection){					
					if("id".equals(item.name)
							|| "card_num".equals(item.name)
							|| "authority".equals(item.name)
							|| "check_type".equals(item.name)
							|| "opendoor_type".equals(item.name)
							|| "face_data".equals(item.name)){
						sb.append(" "+item.name+"=\""+ item.value +"\" ");
					}else if("calid".equals(item.name)){
						sb.append(" "+item.name+"=\""+ cardId +"\" ");
					}
					if("card_num".equals(item.name)){
						memberInfo.put("card_num", item.value);
					}
				}
				Object card_num = memberInfo.get("card_num");
				if("".equals(StringUtil.convertNullToEmptyString(card_num))){
					memberInfo.put("card_num", "");
				}				
				String memberName = (String)memberInfo.get("name");
				sb.append(" name=\""+ memberName +"\" ");
				sb.append(")");
				String Command = sb.toString();
				result = setEmployeeInfo(mainIp,mainPort,mainPassword,Command);
				if(!"".equals(result)){
					ItemCollection = FaceId_Item.GetAllItems(result);
					for (FaceId_Item item : ItemCollection){
						if("result".equals(item.name) && "failed".equals(item.value)){
							message = String.format("向主设备【%s】中更新卡号为 %s 的人员信息失败",mainName,cardId);
							return message;
						}
					}
					message = "";
				}
				for(Map<String,Object> otherDevice:otherDevices){
					String otherIp = (String)otherDevice.get("ip");
					Integer otherPort = (Integer)otherDevice.get("port");
					String otherPassword = (String)otherDevice.get("password");	
					String otherName = (String)otherDevice.get("deviceName");
					connectStatus = (Integer)otherDevice.get("connectStatus");
					if(connectStatus == 2){
						message += String.format("连接设备【%s】失败！\r\n", otherName);
						continue;
					}
					result = setEmployeeInfo(otherIp,otherPort,otherPassword,Command);
					if("fail".equals(result)){
						message += String.format("连接设备【%s】失败！\r\n", otherName);
					}else{
						ItemCollection = FaceId_Item.GetAllItems(result);
						for (FaceId_Item item : ItemCollection){
							if("result".equals(item.name) && "failed".equals(item.value)){
								message += String.format("向设备【%s】中同步卡号为 %s 的人员信息失败\r\n",otherName,cardId);
							}
						}
					}
				}
			}
		}
		return message;
	}
	
	/**
	 * 从汉王门禁设备获取指定ID的员工信息
	 * @param ip
	 * @param port
	 * @param password
	 * @param employeeId
	 * @return
	 */
	public static String getEmployeeInfo(String ip,Integer port,String password,Integer employeeId) {	
		String result = null;
		try(FaceId tcpClient = new FaceId(ip, port)) {
			// 设置设备通信密码
            tcpClient.setSecretKey(password);
            // 根据员工ID，获取员工信息
            String Command = String.format("GetEmployee(id=\"%s\")", employeeId);
            FaceIdAnswer output = new FaceIdAnswer();
            FaceId_ErrorCode ErrorCode = tcpClient.Execute(Command, output, DEVICECHARSET);            
			if (ErrorCode.equals(FaceId_ErrorCode.Success)) {
				System.out.println("获取员工信息成功！");
			} else {
				System.out.println("获取员工信息失败！");
			}
			result = output.answer;
		} catch (Exception e) {
			result = "fail";
			System.out.println("连接设备失败！");
			System.out.println(e.getMessage());
		}
		return result;
	}
	
	/**
	 * 将员工信息存储到汉王设备中
	 * @param ip
	 * @param port
	 * @param password
	 * @param command
	 * @return
	 */
	public static String setEmployeeInfo(String ip,Integer port,String password,String command) {	
		String result = "";
		try(FaceId tcpClient = new FaceId(ip, port)) {
			// 设置设备通信密码
            tcpClient.setSecretKey(password);
            FaceIdAnswer output = new FaceIdAnswer();
            FaceId_ErrorCode ErrorCode = tcpClient.Execute(command, output, DEVICECHARSET);
			if (ErrorCode.equals(FaceId_ErrorCode.Success)) {
				System.out.println("同步员工信息成功！");
			} else {
				System.out.println("同步员工信息失败！");	
			}
			result = output.answer;
		} catch (Exception e) {
			result = "fail";
			System.out.println("连接设备失败！");
			System.out.println(e.getMessage());
		}
		return result;
	}
	
	
	
	/**
	 * 会员解绑
	 * @param devices 设备信息， 主要包括 ip，port，password,deviceName
	 * @param cardId	手环ID(手环编号)
	 * @param memberInfo 会员信息
	 * @return
	 */
	public static String unbindHandCard(List<Map<String,Object>> devices,Integer cardId){
		String message = "";
		String result = "";
		for(Map<String,Object> otherDevice:devices){
			try{
				String ip = (String)otherDevice.get("ip");
				Integer port = (Integer)otherDevice.get("port");
				String password = (String)otherDevice.get("password");	
				String deviceName = (String)otherDevice.get("deviceName");
				Integer connectStatus = (Integer)otherDevice.get("connectStatus");
				if(connectStatus == 2){
					message += String.format("连接设备【%s】失败！\r\n", deviceName);
				}else{
					result = deleteEmployeeInfo(ip,port,password,cardId);
					if("fail".equals(result)){
						message += String.format("连接设备【%s】失败！\r\n", deviceName);
					}
				}
			}catch(Exception ex){
				System.out.println(ex.getMessage());
			}			
		}
		return message;
	}
	
	/**
	 * 从汉王门禁设备中删除指定的员工信息
	 * @param ip
	 * @param port
	 * @param password
	 * @param cardId
	 * @return
	 */
	public static String deleteEmployeeInfo(String ip,Integer port,String password,Integer cardId) {	
		String result = "";
		try(FaceId tcpClient = new FaceId(ip, port)) {
			// 设置设备通信密码
            tcpClient.setSecretKey(password);
            String command = "DeleteEmployee(id=\""+ cardId +"\")";
            FaceIdAnswer output = new FaceIdAnswer();
            FaceId_ErrorCode ErrorCode = tcpClient.Execute(command, output, DEVICECHARSET);
			if (ErrorCode.equals(FaceId_ErrorCode.Success)) {
				System.out.println("删除员工信息成功！");
			} else {
				System.out.println("删除员工信息失败！");
			}
			result = output.answer;
		} catch (Exception e) {
			result = "fail";
			System.out.println("连接设备失败！");
			System.out.println(e.getMessage());
		}
		return result;
	}
	
	/**
	 * 员工绑卡
	 * @param mainDevice 主设备信息，主要包括 ip，port，password,deviceName 连接状态 connectionStatus
	 * @param otherDevice 其它设备信息， 主要包括 ip，port，password,deviceName,连接状态 connectionStatus
	 * @return
	 */
	public static String bindEmployeeHandCard(Map<String,Object> mainDevice,List<Map<String,Object>> otherDevices){
		String message = "";
		String result = "";
		FaceId_Item[] ItemCollection = null;
		String mainIp = (String)mainDevice.get("ip");
		Integer mainPort = (Integer)mainDevice.get("port");
		String mainPassword = (String)mainDevice.get("password");		
		String mainName = (String)mainDevice.get("deviceName");
		Map<Integer,String> commandMap = new HashMap<Integer,String>();
		for(int i = 1; i <= 50; i++){
			String employeeInfoString = getEmployeeInfo(mainIp,mainPort,mainPassword,i);
			if("fail".equals(employeeInfoString)){
				message += String.format("连接主设备【%s】失败,请稍后重试！", mainName);
				return message;
			}
			boolean isContinue = false;
			ItemCollection = FaceId_Item.GetAllItems(employeeInfoString);
			if (ItemCollection != null){
				for (FaceId_Item item : ItemCollection){
					if("result".equals(item.name) && "failed".equals(item.value)){//未知ID，
						isContinue = true;
					}
				}
			}
			if(isContinue == true){//未找到对应的编号
				commandMap.put(i, null);
				continue;
			}
			if (ItemCollection != null){
					StringBuilder sb = new StringBuilder();
					sb.append("SetEmployee( ");
					boolean hasName = false;
					for (FaceId_Item item : ItemCollection){
						if("id".equals(item.name)
								|| "card_num".equals(item.name)
								|| "authority".equals(item.name)
								|| "check_type".equals(item.name)
								|| "opendoor_type".equals(item.name)
								|| "name".equals(item.name)
								|| "face_data".equals(item.name)){
							sb.append(" "+item.name+"=\""+ item.value +"\" ");
						}else if("calid".equals(item.name)){
							sb.append(" "+item.name+"=\""+ i +"\" ");
						}
						if("name".equals(item.name)){
							hasName = true;
						}
					}
					if(hasName == false){
						sb.append(" name=\"\" ");
					}
					sb.append(")");
					commandMap.put(i, sb.toString());
			}
		}
		System.out.println(commandMap.toString());
		for (Map<String, Object> otherDevice : otherDevices) {
			String otherIp = (String) otherDevice.get("ip");
			Integer otherPort = (Integer) otherDevice.get("port");
			String otherPassword = (String) otherDevice.get("password");
			for (Integer key : commandMap.keySet()) {
				System.out.println("Key = " + key);
				String command = commandMap.get(key);
				if (command == null) {
					result = deleteEmployeeInfo(otherIp,otherPort,otherPassword,key);
				} else {
					result = setEmployeeInfo(otherIp, otherPort, otherPassword, command);
				}
				if("fail".equals(result)){
					break;
				}
				System.out.println(String.format("Key = %s,IP:%s,PORT:%s,Passowrd:%s,result:%s,command:%s", key,otherIp,otherPort,otherPassword,result,command));
			}
			if("fail".equals(result)){
				continue;
			}
		}
		return message;
	}
	
	/**
	 * 向前台设备添加测试人员信息
	 * @param mainDevice 前台设备信息
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static String setTestMemberInfoToHanWang(Map<String,Object> mainDevice,JSONObject employeeInfo){
		String result = "";
		StringBuilder sb = new StringBuilder();
		sb.append("SetEmployee( ");		
		Iterator<String> employeeIterator = employeeInfo.keys();
//        while(employeeIterator.hasNext()){
//            String key = (String) employeeIterator.next();
//            key = StringUtil.convertNullToEmptyString(key);
//            String value = StringUtil.convertNullToEmptyString(employeeInfo.getString(key));
//            sb.append(" "+ key +"=\""+ value +"\" ");
//        }
		while (employeeIterator.hasNext()) {
			String key = (String) employeeIterator.next();
			key = StringUtil.convertNullToEmptyString(key);
			String value = StringUtil.convertNullToEmptyString(employeeInfo.getString(key));			
			if("face_datas".equals(key)){
     			JSONArray faceDatas = employeeInfo.getJSONArray(key);
     			for(int i = 0; i < faceDatas.size(); i++){
     				JSONObject face = faceDatas.getJSONObject(i);
     				String face_data = face.getString("face_data");
     				sb.append(" face_data=\""+ face_data +"\" ");
     			}            			
     		}else{
     			sb.append(" " + key + "=\"" + value + "\" ");
     		}
		}
		sb.append(")");
		String command = sb.toString();
		
		String mainIp = (String)mainDevice.get("ip");
		Integer mainPort = (Integer)mainDevice.get("port");
		String mainPassword = (String)mainDevice.get("password");		
		String mainName = (String)mainDevice.get("deviceName");	
		
		result = setEmployeeInfo(mainIp, mainPort, mainPassword, command);
		result = String.format("设备【%s】执行结果：%s", mainName,result);
		return result;
	}
	
	
	
	/**
	 * 更新汉王设备管理员信息
	 * @param mainDevice 主设备信息，主要包括 ip，port，password,deviceName 连接状态 connectionStatus
	 * @param otherDevice 其它设备信息， 主要包括 ip，port，password,deviceName,连接状态 connectionStatus
	 * @return
	 */
	public static String updateHanWangManager(Map<String,Object> mainDevice,List<Map<String,Object>> otherDevices){
		String message = "";
		String result = "";
		FaceId_Item[] ItemCollection = null;
		String mainIp = (String)mainDevice.get("ip");
		Integer mainPort = (Integer)mainDevice.get("port");
		String mainPassword = (String)mainDevice.get("password");		
		String mainName = (String)mainDevice.get("deviceName");
		boolean mainStatus = DetectDevice(mainIp,mainPort,mainPassword);
		if(mainStatus == false){
			message = String.format("连接主设备【%s】失败,请稍后重试！", mainName);
			return message;
		}
		List<String> managerIds = getManagerIDList(mainIp,mainPort,mainPassword);
		if(managerIds == null || managerIds.size() == 0){
			message = String.format("主设备【%s】中未找到管理员信息，请先录入管理员信息！", mainName);
			return message;
		}
		Map<Integer,String> commandMap = new HashMap<Integer,String>();
		for(int i = 0; i < managerIds.size(); i++){
			String managerInfoString = getManagerInfo(mainIp,mainPort,mainPassword,managerIds.get(i));
			if("fail".equals(managerInfoString)){
				message += String.format("连接主设备【%s】失败,请稍后重试！", mainName);
				return message;
			}
			ItemCollection = FaceId_Item.GetAllItems(managerInfoString);
			if (ItemCollection != null) {
				StringBuilder sb = new StringBuilder();
				sb.append("SetManager( ");
				boolean hasName = false;
				for (FaceId_Item item : ItemCollection) {
					if("name".equals(item.name)
							|| "id".equals(item.name)
							|| "valid".equals(item.name)
							|| "card_num".equals(item.name)
							|| "pass_word".equals(item.name)
							|| "enter_type".equals(item.name)
							|| "manager_type".equals(item.name)
							|| "face_data".equals(item.name))
					sb.append(" " + item.name + "=\"" + item.value + "\" ");
					if ("name".equals(item.name)) {
						hasName = true;
					}
				}
				if (hasName == false) {
					sb.append(" name=\"\" ");
				}
				if(sb.indexOf("valid=\"") < 0){
					sb.append(" valid=\"\" ");
				}
				if(sb.indexOf("pass_word=\"") < 0){
					sb.append(" pass_word=\"\" ");
				}
				sb.append(")");
				commandMap.put(i, sb.toString());
			}
		}
		System.out.println(commandMap.toString());
		for (Map<String, Object> otherDevice : otherDevices) {
			String otherIp = (String) otherDevice.get("ip");
			Integer otherPort = (Integer) otherDevice.get("port");
			String otherPassword = (String) otherDevice.get("password");
			String otherName = (String)mainDevice.get("deviceName");
			boolean otherStatus = DetectDevice(mainIp,mainPort,mainPassword);
			if(otherStatus == false){
				message  += String.format("连接设备【%s】失败\r\n", otherName);
				continue;
			}			
			InitDeviceAdmin(otherIp, otherPort, otherPassword);			
			for (Integer key : commandMap.keySet()) {
				System.out.println("Key = " + key);
				String command = commandMap.get(key);
				if (command != null) {
					result = SetManager(otherIp, otherPort, otherPassword, command);
				}
				if("fail".equals(result)){
					break;
				}
			}
		}
		return message;
	}
	
	
	/**
	 * 从汉王门禁设备获取管理员ID List
	 * @param ip
	 * @param port
	 * @param password
	 * @param employeeId
	 * @return
	 */
	public static List<String> getManagerIDList(String ip,Integer port,String password) {	
		List<String> managerIds = new ArrayList<String>();
		try(FaceId tcpClient = new FaceId(ip, port)) {
			// 设置设备通信密码
            tcpClient.setSecretKey(password);
            // 根据员工ID，获取员工信息
            String Command = "GetManagerID()";
            FaceIdAnswer output = new FaceIdAnswer();
            FaceId_ErrorCode ErrorCode = tcpClient.Execute(Command, output, DEVICECHARSET);            
			if (ErrorCode.equals(FaceId_ErrorCode.Success)) {
				FaceId_Item[] ItemCollection = FaceId_Item.GetAllItems(output.answer); 
                if (ItemCollection != null){
                    for (FaceId_Item item : ItemCollection){
                    	if("id".equals(item.name)){
                    		managerIds.add(item.value);
                    	}
                    }
                }
			}
		} catch (Exception e) {
			System.out.println("连接设备失败！");
			System.out.println(e.getMessage());
		}
		return managerIds;
	}
	
	/**
	 * 从汉王门禁设备获取指定ID管理员信息
	 * @param ip
	 * @param port
	 * @param password
	 * @param employeeId
	 * @return
	 */
	public static String getManagerInfo(String ip,Integer port,String password,String managerId) {	
		String result = "";
		try(FaceId tcpClient = new FaceId(ip, port)) {
			// 设置设备通信密码
            tcpClient.setSecretKey(password);
            // 根据员工ID，获取员工信息
            String Command = String.format("GetManager(id=\"%s\")", managerId);
            FaceIdAnswer output = new FaceIdAnswer();
            FaceId_ErrorCode ErrorCode = tcpClient.Execute(Command, output, DEVICECHARSET);            
			if (ErrorCode.equals(FaceId_ErrorCode.Success)) {
				System.out.println("获取管理员信息成功！");
			} else {
				System.out.println("获取管理员信息失败！");
			}
			result = output.answer;
		} catch (Exception e) {
			result = "fail";
			System.out.println("连接设备失败！");
			System.out.println(e.getMessage());
		}
		return result;
	}
	
	/**
	 * 清空汉王设备管理员信息
	 * @param ip
	 * @param port
	 * @param password
	 * @return
	 */
	public static boolean InitDeviceAdmin(String ip,Integer port,String password){
		boolean result = false;
		try(FaceId tcpClient = new FaceId(ip, port)) {
            // 设置通信密码
            tcpClient.setSecretKey(password);   // 注意：密码和设备通信密码一致  
            // 获取考勤记录
            String Command = "InitDeviceAdmin()";
            FaceIdAnswer output = new FaceIdAnswer();
            FaceId_ErrorCode ErrorCode = tcpClient.Execute(Command, output, DEVICECHARSET);
			if (ErrorCode.equals(FaceId_ErrorCode.Success)) {
				FaceId_Item[] ItemCollection = FaceId_Item.GetAllItems(output.answer); 
                if (ItemCollection != null){
                    for (FaceId_Item item : ItemCollection){
                    	if("result".equals(item.name) && "success".equals(item.value)){
                    		result = true;
                			break;
                		}
                    }
                }
			}
		} catch (Exception e) {
			System.out.println("连接设备失败！");
			System.out.println(e.getMessage());
		}
		return result;
	}
	
	/**
	 * 设备汉王设备管理员信息
	 * @param ip
	 * @param port
	 * @param password
	 * @param command
	 * @return
	 */
	public static String SetManager(String ip,Integer port,String password,String command) {		
		String result = "";
		try(FaceId tcpClient = new FaceId(ip, port)) {
			// 设置设备通信密码
            tcpClient.setSecretKey(password);
            FaceIdAnswer output = new FaceIdAnswer();
            FaceId_ErrorCode ErrorCode = tcpClient.Execute(command, output, DEVICECHARSET);
			if (ErrorCode.equals(FaceId_ErrorCode.Success)) {
				System.out.println("同步管理信息成功！");
			} else {
				System.out.println("同步管理信息失败！");	
			}
			result = output.answer;
		} catch (Exception e) {
			result = "fail";
			System.out.println("连接设备失败！");
			System.out.println(e.getMessage());
		}
		return result;
	}
	
	/**
	 * 检测设备是否存在，或者是否连接正常
	 * @param ip
	 * @param port
	 * @param password
	 * @return
	 */
	public static boolean DetectDevice(String ip,Integer port,String password){
		boolean isConnection = false;
		try(FaceId tcpClient = new FaceId(ip, port)) {					
            tcpClient.setSecretKey(password);
            // 检测设备是否存在
            String Command = "DetectDevice()";
            FaceIdAnswer output = new FaceIdAnswer();
            FaceId_ErrorCode ErrorCode = tcpClient.Execute(Command, output, DEVICECHARSET);
			if (ErrorCode.equals(FaceId_ErrorCode.Success)) {
				System.out.println(output.answer);
				FaceId_Item[] ItemCollection = FaceId_Item.GetAllItems(output.answer); 
                if (ItemCollection != null){
                	for (FaceId_Item item : ItemCollection){
                		if("result".equals(item.name) && "success".equals(item.value)){
                			isConnection = true;
                			break;
                		}
                	}
                }
			}
		} catch (Exception e) {
			System.out.println("检测设备失败！");
			System.out.println(e.getMessage());
		}
		return isConnection;
	}
	
	
}
